home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / Assemblers / 68kasm / directive.c < prev    next >
C/C++ Source or Header  |  1995-07-26  |  10KB  |  436 lines

  1. /******************************************************************************
  2.  * $Id: directive.c,v 1.1 1994/08/29 23:56:47 bmott Exp $
  3.  ******************************************************************************
  4.  *
  5.  *
  6.  *        DIRECTIVE.C
  7.  *        Directive Routines for 68000 Assembler
  8.  *
  9.  * Description: The functions in this file carry out the functions of
  10.  *        assembler directives. All the functions share the same
  11.  *        calling sequence: 
  12.  *
  13.  *            general_name(size, label, op, errorPtr)
  14.  *            int size;
  15.  *            char *label, *op;
  16.  *            int *errorPtr;
  17.  *
  18.  *        The size argument contains the size code that was
  19.  *        specified with the instruction (using the definitions
  20.  *        in ASM.H) or 0 if no size code was specified. The label
  21.  *        argument is a pointer to a string (which may be empty)
  22.  *        containing the label from the line containing the
  23.  *        directive. The op argument is a pointer to the first
  24.  *        non-blank character after the name of the directive,
  25.  *        i.e., the operand(s) of the directive. The errorPtr
  26.  *        argument is used to return a status via the standard
  27.  *        mechanism. 
  28.  *
  29.  *      Author: Paul McKee
  30.  *        ECE492    North Carolina State University
  31.  *
  32.  *        Date:    12/13/86
  33.  *
  34.  *   Copyright 1990-1991 North Carolina State University. All Rights Reserved.
  35.  *
  36.  ******************************************************************************
  37.  * $Log: directive.c,v $
  38.  * Revision 1.1  1994/08/29  23:56:47  bmott
  39.  * Initial revision
  40.  *
  41.  *****************************************************************************/
  42.  
  43.  
  44. #include <stdio.h>
  45. #include <ctype.h>
  46. #include "asm.h"
  47.  
  48. extern int loc;
  49. extern char pass2, endFlag, listFlag;
  50. symbolDef *define();
  51.  
  52. extern char *listPtr;    /* Pointer to buffer where listing line is assembled
  53.                (Used to put =XXXXXXXX in the listing for EQU's and SET's */
  54.  
  55.  
  56. /***********************************************************************
  57.  *
  58.  *    Function org implements the ORG directive.
  59.  *
  60.  ***********************************************************************/
  61.  
  62. org(size, label, op, errorPtr)
  63. int size;
  64. char *label, *op;
  65. int *errorPtr;
  66. {
  67. int newLoc;
  68. char backRef;
  69. char *eval();
  70.  
  71.     if (size)
  72.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  73.     if (!*op) {
  74.         NEWERROR(*errorPtr, SYNTAX);
  75.         return;
  76.         }
  77.     op = eval(op, &newLoc, &backRef, errorPtr);
  78.     if (*errorPtr < SEVERE && !backRef) {
  79.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  80.         }
  81.     else if (*errorPtr < ERROR) {
  82.         if (isspace(*op) || !*op) {
  83.             /* Check for an odd value, adjust to one higher */
  84.             if (newLoc & 1) {
  85.                 NEWERROR(*errorPtr, ODD_ADDRESS);
  86.                 newLoc++;
  87.                 }
  88.             loc = newLoc;
  89.             /* Define the label attached to this directive, if any */
  90.             if (*label)
  91.                 define(label, loc, pass2, errorPtr);
  92.             /* Show new location counter on listing */
  93.             listLoc();
  94.             }
  95.         else
  96.             NEWERROR(*errorPtr, SYNTAX);
  97.         }
  98. }
  99.  
  100.  
  101. /***********************************************************************
  102.  *
  103.  *    Function end implements the END directive.
  104.  *
  105.  ***********************************************************************/
  106.  
  107. End(size, label, op, errorPtr)
  108. int size;
  109. char *label, *op;
  110. int *errorPtr;
  111. {
  112.     if (size)
  113.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  114.     endFlag = TRUE;
  115. }
  116.  
  117.  
  118. /***********************************************************************
  119.  *
  120.  *    Function equ implements the EQU directive.
  121.  *
  122.  ***********************************************************************/
  123.  
  124. equ(size, label, op, errorPtr)
  125. int size;
  126. char *label, *op;
  127. int *errorPtr;
  128. {
  129. int value;
  130. char backRef;
  131. char *eval();
  132.  
  133.     if (size)
  134.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  135.     if (!*op) {
  136.         NEWERROR(*errorPtr, SYNTAX);
  137.         return;
  138.         }
  139.     op = eval(op, &value, &backRef, errorPtr);
  140.     if (*errorPtr < SEVERE && !backRef) {
  141.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  142.         }
  143.     else if (*errorPtr < ERROR)
  144.         if (isspace(*op) || !*op)
  145.             if (!*label) {
  146.                 NEWERROR(*errorPtr, LABEL_REQUIRED);
  147.                 }
  148.             else {        
  149.                 define(label, value, pass2, errorPtr);
  150.                 if (pass2 && listFlag && *errorPtr < MINOR) {
  151.                     sprintf(listPtr, "=%08X ", value);
  152.                     listPtr += 10;
  153.                     }
  154.                 }
  155.         else
  156.             NEWERROR(*errorPtr, SYNTAX);
  157. }
  158.  
  159.  
  160. /***********************************************************************
  161.  *
  162.  *    Function set implements the SET directive.
  163.  *
  164.  ***********************************************************************/
  165.  
  166. set(size, label, op, errorPtr)
  167. int size;
  168. char *label, *op;
  169. int *errorPtr;
  170. {
  171. int value, error;
  172. char backRef;
  173. symbolDef *symbol;
  174. char *eval();
  175.  
  176.     if (size)
  177.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  178.     if (!*op) {
  179.         NEWERROR(*errorPtr, SYNTAX);
  180.         return;
  181.         }
  182.     error = OK;
  183.     op = eval(op, &value, &backRef, errorPtr);
  184.     if (*errorPtr < SEVERE && !backRef) {
  185.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  186.         }
  187.     if (*errorPtr > ERROR)
  188.         if (isspace(*op) || !*op)
  189.             if (!*label) {
  190.                 NEWERROR(*errorPtr, LABEL_REQUIRED);
  191.                 }
  192.             else {        
  193.                 error = OK;
  194.                 symbol = define(label, value, pass2, &error);
  195.                 if (error == MULTIPLE_DEFS)
  196.                     if (symbol->flags & REDEFINABLE)
  197.                         symbol->value = value;
  198.                     else {
  199.                         NEWERROR(*errorPtr, MULTIPLE_DEFS);
  200.                         return;
  201.                         }
  202.                 symbol->flags |= REDEFINABLE;
  203.                 if (pass2 & listFlag) {
  204.                     sprintf(listPtr, "=%08X ", value);
  205.                     listPtr += 10;
  206.                     }
  207.                 }
  208.         else
  209.             NEWERROR(*errorPtr, SYNTAX);
  210. }
  211.  
  212.  
  213. /***********************************************************************
  214.  *
  215.  *    Function dc implements the DC directive.
  216.  *
  217.  ***********************************************************************/
  218.  
  219. dc(size, label, op, errorPtr)
  220. int size;
  221. char *label, *op;
  222. int *errorPtr;
  223. {
  224. int outVal;
  225. char backRef;
  226. char string[260], *p, *collect(), *eval();
  227.  
  228.     if (size == SHORT) {
  229.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  230.         size = WORD;
  231.         }
  232.     else if (!size)
  233.         size = WORD;
  234.     /* Move location counter to a word boundary and fix the listing if doing
  235.        DC.W or DC.L (but not if doing DC.B, so DC.B's can be contiguous) */
  236.     if ((size & (WORD | LONG)) && (loc & 1)) {
  237.         loc++;
  238.         listLoc();
  239.         }
  240.     /* Define the label attached to this directive, if any */
  241.     if (*label)
  242.         define(label, loc, pass2, errorPtr);
  243.     /* Check for the presence of the operand list */
  244.     if (!*op) {
  245.         NEWERROR(*errorPtr, SYNTAX);
  246.         return;
  247.         }
  248.     do {
  249.         if (*op == '\'') {
  250.             op = collect(++op, string);
  251.             if (!isspace(*op) && *op != ',') {
  252.                 NEWERROR(*errorPtr, SYNTAX);
  253.                 return;
  254.                 }
  255.             p = string;
  256.             while (*p) {
  257.                 outVal = *p++;
  258.                 if (size > BYTE)
  259.                     outVal = (outVal << 8) + *p++;
  260.                 if (size > WORD) {
  261.                     outVal = (outVal << 16) + (*p++ << 8);
  262.                     outVal += *p++;
  263.                     }
  264.                 if (pass2)
  265.                     output(outVal, size);
  266.                 loc += size;
  267.                 }
  268.             }
  269.         else {
  270.             op = eval(op, &outVal, &backRef, errorPtr);
  271.             if (*errorPtr > SEVERE)
  272.                 return;
  273.             if (!isspace(*op) && *op != ',') {
  274.                 NEWERROR(*errorPtr, SYNTAX);
  275.                 return;
  276.                 }
  277.             if (pass2)
  278.                 output(outVal, size);
  279.             loc += size;
  280.             if (size == BYTE && (outVal < -128 || outVal > 255)) {
  281.                 NEWERROR(*errorPtr, INV_8_BIT_DATA);
  282.                 }
  283.             else if (size == WORD && (outVal < -32768 || outVal > 65535))
  284.                 NEWERROR(*errorPtr, INV_16_BIT_DATA);
  285.             }
  286.     } while (*op++ == ',');
  287.     --op;
  288.     if (!isspace(*op) && *op)
  289.         NEWERROR(*errorPtr, SYNTAX);
  290. }
  291.  
  292. /**********************************************************************
  293.  *
  294.  *    Function collect parses strings for dc. Each output string
  295.  *    is padded with four nulls at the end.
  296.  *
  297.  **********************************************************************/
  298.  
  299. char *collect(s, d)
  300. char *s, *d;
  301. {
  302.     while (*s) {
  303.         if (*s == '\'')
  304.             if (*(s+1) == '\'') {
  305.                 *d++ = *s;
  306.                 s += 2;
  307.                 }
  308.             else {
  309.                 *d++ = '\0';
  310.                 *d++ = '\0';
  311.                 *d++ = '\0';
  312.                 *d++ = '\0';
  313.                 return ++s;
  314.                 }
  315.         else
  316.             *d++ = *s++;
  317.         }
  318.     return s;
  319. }
  320.         
  321.  
  322. /***********************************************************************
  323.  *
  324.  *    Function dcb implements the DCB directive.
  325.  *
  326.  ***********************************************************************/
  327.  
  328. dcb(size, label, op, errorPtr)
  329. int size;
  330. char *label, *op;
  331. int *errorPtr;
  332. {
  333. int blockSize, blockVal, i;
  334. char *eval();
  335. char backRef;
  336.  
  337.     if (size == SHORT) {
  338.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  339.         size = WORD;
  340.         }
  341.     else if (!size)
  342.         size = WORD;
  343.     /* Move location counter to a word boundary and fix the listing if doing
  344.        DCB.W or DCB.L (but not if doing DCB.B, so DCB.B's can be contiguous) */
  345.     if ((size & (WORD | LONG)) && (loc & 1)) {
  346.         loc++;
  347.         listLoc();
  348.         }
  349.     /* Define the label attached to this directive, if any */
  350.     if (*label)
  351.         define(label, loc, pass2, errorPtr);
  352.     /* Evaluate the size of the block (in bytes, words, or longwords) */
  353.     op = eval(op, &blockSize, &backRef, errorPtr);
  354.     if (*errorPtr < SEVERE && !backRef) {
  355.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  356.         return;
  357.         }
  358.     if (*errorPtr > SEVERE)
  359.         return;
  360.     if (*op != ',') {
  361.         NEWERROR(*errorPtr, SYNTAX);
  362.         return;
  363.         }
  364.     if (blockSize < 0) {
  365.         NEWERROR(*errorPtr, INV_LENGTH);
  366.         return;
  367.         }
  368.     /* Evaluate the data to put in block */
  369.     op = eval(++op, &blockVal, &backRef, errorPtr);
  370.     if (*errorPtr < SEVERE) {
  371.         if (!isspace(*op) && *op) {
  372.             NEWERROR(*errorPtr, SYNTAX);
  373.             return;
  374.             }
  375.         /* On pass 2, output the block of values directly
  376.            to the object file (without putting them in the listing) */
  377.         if (pass2)
  378.             for (i = 0; i < blockSize; i++) {
  379.                 outputObj(loc, blockVal, size);
  380.                 loc += size;
  381.                 }
  382.         else
  383.             loc += blockSize * size;
  384.         }
  385. }
  386.  
  387.  
  388. /***********************************************************************
  389.  *
  390.  *    Function ds implements the DS directive.
  391.  *
  392.  ***********************************************************************/
  393.  
  394. ds(size, label, op, errorPtr)
  395. int size;
  396. char *label, *op;
  397. int *errorPtr;
  398. {
  399. int blockSize;
  400. char backRef;
  401. char *eval();
  402.  
  403.     if (size == SHORT) {
  404.         NEWERROR(*errorPtr, INV_SIZE_CODE);
  405.         size = WORD;
  406.         }
  407.     else if (!size)
  408.         size = WORD;
  409.     /* Move location counter to a word boundary and fix the listing if doing
  410.        DS.W or DS.L (but not if doing DS.B, so DS.B's can be contiguous) */
  411.     if ((size & (WORD | LONG)) && (loc & 1)) {
  412.         loc++;
  413.         listLoc();
  414.         }
  415.     /* Define the label attached to this directive, if any */
  416.     if (*label)
  417.         define(label, loc, pass2, errorPtr);
  418.     /* Evaluate the size of the block (in bytes, words, or longwords) */
  419.     op = eval(op, &blockSize, &backRef, errorPtr);
  420.     if (*errorPtr < SEVERE && !backRef) {
  421.         NEWERROR(*errorPtr, INV_FORWARD_REF);
  422.         return;
  423.         }
  424.     if (*errorPtr > SEVERE)
  425.         return;
  426.     if (!isspace(*op) && *op) {
  427.         NEWERROR(*errorPtr, SYNTAX);
  428.         return;
  429.         }
  430.     if (blockSize < 0) {
  431.         NEWERROR(*errorPtr, INV_LENGTH);
  432.         return;
  433.         }
  434.     loc += blockSize * size;
  435. }
  436.